/**
 * api 全局参数校验
 * 
 */

const Ajv = require('ajv');
const ajv = new Ajv();


module.exports = (app) => {
    const $schema = 'http://json-schema.org/draft-07/schema#'
    return async (ctx, next) => {
        // 只对api校验
        if (ctx.path.indexOf('/api') < 0) {
            return await next();
        }

        // 获取请求参数
        const { query, headers, body } = ctx.request;
        const { params, path, method } = ctx;

        app.logger.info(`[${method} ${path}] body: ${JSON.stringify(body)}`);
        app.logger.info(`[${method} ${path}] query: ${JSON.stringify(query)}`);
        app.logger.info(`[${method} ${path}] params: ${JSON.stringify(params)}`);
        // app.logger.info(`[${method} ${path}] headers: ${JSON.stringify(headers)}`);

        const schema = app.routerSchema[path]?.[method.toLowerCase()];

        // console.log(schema,'----');
        

        if (!schema) {
            return await next();
        }

        let valid = true;

        // avj 校验器
        let validate;

        // 校验headers
        if (valid && schema && schema.headers) {
            schema.headers.$schema = $schema;
            validate = ajv.compile(schema.headers);
            valid = validate(headers);
        }

        // 校验body
        if (valid && schema && schema.body) {
            schema.body.$schema = $schema;
            validate = ajv.compile(schema.body);
            valid = validate(body);
        }

        // 校验parmas
        if (valid && schema && schema.params) {
            schema.params.$schema = $schema;
            validate = ajv.compile(schema.params);
            valid = validate(params);
        }

        // 校验query
        if (valid && schema && schema.query) {
            schema.query.$schema = $schema;
            validate = ajv.compile(schema.query);
            valid = validate(query);
        }

        if (!valid) {
            ctx.status = 200;
            return ctx.body = {
                success: false,
                msg: `request validate fail: ${ajv.errorsText(validate.errors)}`,
                code: 442
            }
        }

        await next();
    }
}